﻿using System;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;
using EffiProz.Core;
using EffiProz.Core.Lib;
using EffiProz.Core.Persist;

namespace EffiProz.Server
{
    class Program
    {        
        static void Main(string[] args)
        {
            bool isWebServer = false;
            bool isTls = false;
            X509Certificate serverCertificate = null;


            if (args.Length > 0)
            {
                switch (args[0].ToUpper())
                {                   
                    case "EFZS":
                        isWebServer = false;
                        isTls = true;
                        break;
                    case "HTTP":
                        isWebServer = true;
                        isTls = false;
                        break;
                    case "HTTPS":
                        isWebServer = true;
                        isTls = true;
                        break;
                    case "EFZ":
                    default:
                        isWebServer = false;
                        isTls = false;
                        break;
                }              
            }

            if (isTls)
            {
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

                string certificateName = args.Length > 1 ? args[1] : "EffiProz";

            
                store.Open(OpenFlags.ReadOnly);
                X509CertificateCollection certificateCollection =
                store.Certificates.Find(X509FindType.FindBySubjectName,
                                        certificateName, false);

                if (certificateCollection.Count > 0)
                    serverCertificate = certificateCollection[0];

                if (serverCertificate == null)
                    throw new ArgumentException("No Certificate could be found in name " + certificateName);


            }

            String propsPath = isWebServer ? FileUtil.GetDefaultInstance().CanonicalOrAbsolutePath("webserver"): 
                FileUtil.GetDefaultInstance().CanonicalOrAbsolutePath("server");
            EffiProzProperties fileProps =
                ServerConfiguration.getPropertiesFromFile(propsPath);
            EffiProzProperties props = fileProps == null ? new EffiProzProperties()
                                                           : fileProps;
            EffiProzProperties stringProps = null;

            try
            {
                stringProps = EffiProzProperties.argArrayToProps(args,
                        ServerConstants.SC_KEY_PREFIX);
            }
            catch (IndexOutOfRangeException )
            {

                // I'd like to exit with 0 here, but it's possible that user
                // has called main() programmatically and does not want us to
                // exit.
                if(isWebServer)
                    Console.WriteLine(Server.getHelp("webserver.help"));
                else
                    Console.WriteLine(Server.getHelp("server.help"));


                return;
            }

            if (stringProps != null)
            {
                if (stringProps.getErrorKeys().Length != 0)
                {
                    if (isWebServer)
                        Console.WriteLine(Server.getHelp("webserver.help"));
                    else
                        Console.WriteLine(Server.getHelp("server.help"));

                    return;
                }

                props.addProperties(stringProps);
            }

            ServerConfiguration.translateDefaultDatabaseProperty(props);

            // Standard behaviour when started from the command line
            // is to halt the VM when the server shuts down.  This may, of
            // course, be overridden by whatever, if any, security policy
            // is in place.
            ServerConfiguration.translateDefaultNoSystemExitProperty(props);

            // finished setting up properties;
            Server server;
            if (!isTls)
            {
                if (isWebServer)
                    server = new WebServer();
                else
                    server = new Server();
            }
            else
            {
                if (isWebServer)
                    server = new WebServer(serverCertificate);
                else
                    server = new Server(serverCertificate);
            }

            try
            {
                server.setProperties(props);
            }
            catch (Exception e)
            {
                server.printError("Failed to set properties");
                server.printStackTrace(e);

                return;
            }

            // now messages go to the channel specified in properties
            server.print("Startup sequence initiated from main() method");

            if (fileProps != null)
            {
                server.print("Loaded properties from [" + propsPath
                             + ".properties]");
            }
            else
            {
                server.print("Could not load properties from file");
                server.print("Using cli/default properties only");
            }

            server.start();

            Console.ReadKey();
        }
    }
}
